#!/bin/bash
# compile and install zabbix in ubuntu

set -u -e
#########################################
# variable region #

ZABBIX_VERSION="6.0.30"
ZABBIX_INSTALL_PATH="/usr/local/zabbix"
ZABBIX_SRC_PATH="/usr/local/src"
ZABBIX_PACK_NAME="zabbix-${ZABBIX_VERSION}.tar.gz"
ZABBIX_DATABASE_TYPE="--with-mysql" # alternatively, --with-postgresql
ZABBIX_DBHOST="localhost"
ZABBIX_DBNAME="zabbix"
ZABBIX_DBUSER="zabbix"
ZABBIX_DBPASSWORD="123456"
ZABBIX_DBPORT="3306"


GOLANG_VERSION="1.22.4"
GO_INSTALL_PATH="/usr/local"
GOLANG_PACK_NAME="go${GOLANG_VERSION}.linux-amd64.tar.gz"


#########################################
## function region #

#declare -f color
#declare -f determine_user
#declare -f create_account # $1 is group name,$2 is user name
#declare -f uncompress_file # $1 is package name,$2 is install path
#declare -f config_golang_env
#declare -f uncompress_zabbix_to_src_path
#declare -f complile_zabbix
#declare -f create_zabbix_service
#declare -f change_zabbix_configfile
#declare -f set_zabbix_configfile

#########################################
color() {
    local message="$1"
    local status="$2"
    local terminal_width
    terminal_width=$(tput cols)
    local middle_column=$(( terminal_width / 2))
    local SETCOLOR_SUCCESS="\033[1;32m"  # 绿色
    local SETCOLOR_FAILURE="\033[1;31m"  # 红色
    local SETCOLOR_WARNING="\033[1;33m"  # 黄色
    local SETCOLOR_NORMAL="\033[0m"      # 重置颜色
    printf '%s\n\033[%sG' "${message}"  "${middle_column}"
    # Print the status message
    printf "["
    case ${status} in
        success|0)
            echo -en  "${SETCOLOR_SUCCESS}  OK  "
            ;;
        failure|1)
            echo -en  "${SETCOLOR_FAILURE}FAILED"
            ;;
        *)
            echo -en "${SETCOLOR_WARNING}WARNING"
            ;;
    esac
    echo -e "${SETCOLOR_NORMAL}]"
}

determine_user () {
    if [ "$(id -u)" -ne 0 ];then
        color "请以管理员用户运行此脚本." failure
        exit
    fi
}

create_account () { # 1 is group name,$2 is user name
    if id "${1}" &> /dev/null;then
        color "group ${1} have exist!" warning
    else
        if groupadd -r "${1}";then
            color "create group  ${1}" success
        else
            color "create group  ${1}" failure
        fi
    fi

    if id "${2}" &> /dev/null;then
        color "user ${2} have exist!" warning
    else
        if useradd -r -g "${2}"  -s /sbin/nologin -M -c "Zabbix Monitoring System" "${2}";then
            color "create user  ${2}" success
        else
            color "create user  ${2}" failure
        fi
    fi
}

uncompress_file () { # $1 is package name,$2 is install path
    if [ -e "${1}" ];then
        color "当前路径$(pwd)已找到${1}，解压到${2}" success
        tar -xvf "${1}" -C "${2}"
    else
        color "当前路径下不存在${1} 压缩包，请先将压缩包放到当前目录后再执行此脚本" failure
        exit
    fi
}

config_golang_env () {
    cat > /etc/profile.d/golang.sh <<-EOF
    export GOROOT=${GO_INSTALL_PATH}/go
    export PATH=\$PATH:\$GOROOT/bin
EOF
    # shellcheck disable=SC1091
    source "/etc/profile.d/golang.sh"
    go version && color "已完成go的安装." success
}

uncompress_zabbix_to_src_path () {
    if [ -d /${ZABBIX_SRC_PATH}/zabbix-${ZABBIX_VERSION} ];then
        color "${ZABBIX_SRC_PATH}/zabbix-${ZABBIX_VERSION} have exist,\
        dont uncompress ${GOLANG_PACK_NAME}" warning
    else
        uncompress_file ${ZABBIX_PACK_NAME} ${ZABBIX_SRC_PATH}
        color "uncompress ${GOLANG_PACK_NAME} to ${ZABBIX_SRC_PATH}/zabbix-${ZABBIX_VERSION}" success
    fi
}

complile_zabbix () {
    color "use apt repository to install complie needed package" warning
    apt update
    apt install -y make gcc zlib1g-dev libevent-dev libpcre3 libpcre3-dev \
      libxml2 libxml2-dev   pkg-config libmysqlclient-dev libcurl4-gnutls-dev \
      libsnmp-dev openjdk-8-jdk openipmi libopenipmi-dev libpq-dev
    if [ -e ${ZABBIX_INSTALL_PATH}/sbin/zabbix_server ];then
        color "find ${ZABBIX_INSTALL_PATH}/sbin/zabbix_server ,dont continue complile." warning
    else
        color "compliling zabbix,need 3 steps ..." warning
        cd "${ZABBIX_SRC_PATH}/zabbix-${ZABBIX_VERSION}"
        ./configure --prefix=${ZABBIX_INSTALL_PATH} \
        --enable-server --enable-agent --enable-agent2 --enable-proxy \
        --enable-ipv6 --with-libcurl --with-libxml2 \
        ${ZABBIX_DATABASE_TYPE} --with-net-snmp --with-openipmi --enable-java \
        && color "complile step 1,create makefile success!" success || \
        { color "complile step 1,create makefile fail." failure;exit; }

        make && color "complile step 2,make binary file success!" success || \
        { color "complile step 2,make binary file fail." failure;exit; }

        make install && color "complile step 3,copy binary file to ${ZABBIX_INSTALL_PATH} success!" success || \
        { color "complile step 3,copy binary file to ${ZABBIX_INSTALL_PATH} fail." failure;exit; }
    fi
}   


create_zabbix_service () {
    if [ -e /lib/systemd/system/zabbix-server.service ] || [ -e /etc/systemd/system/zabbix-server.service ];then
        color "zabbix-server.service has exist." warning
    else

cat > /etc/systemd/system/zabbix-server.service<<EOF
[Unit]
Description=Zabbix Server
After=syslog.target
After=network.target
[Service]
Environment="CONFFILE=${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
EnvironmentFile=-/etc/default/zabbix-server
Type=forking
Restart=on-failure
PIDFile=/tmp/zabbix_server.pid
KillMode=control-group
ExecStart=${ZABBIX_INSTALL_PATH}/sbin/zabbix_server -c \$CONFFILE
ExecStop=/bin/bash -c '[ -n "\$1" ] && kill -s TERM "\$1"' -- "\$MAINPID"
RestartSec=10s
TimeoutSec=infinity
[Install]
WantedBy=multi-user.target
EOF

    fi
    if [ -e /lib/systemd/system/zabbix-agent.service ] || [ -e /etc/systemd/system/zabbix-agent.service ];then
        color "zabbix-agent.service has exist." warning
    else

cat > /etc/systemd/system/zabbix-agent.service<<-EOF
[Unit]
Description=Zabbix Agent
After=syslog.target
After=network.target
[Service]
User=zabbix
Group=zabbix
Environment="CONFFILE=${ZABBIX_INSTALL_PATH}/etc/zabbix_agentd.conf"
EnvironmentFile=-/etc/default/zabbix-agent
Type=forking
Restart=on-failure
PIDFile=/tmp/zabbix_agentd.pid
KillMode=control-group
ExecStart=${ZABBIX_INSTALL_PATH}/sbin/zabbix_agentd -c \$CONFFILE
ExecStop=/bin/sh -c '[ -n "\$1" ] && kill -s TERM "\$1"' -- "\$MAINPID"
RestartSec=10s
[Install]
WantedBy=multi-user.target
EOF
    fi
    systemctl daemon-reload
}

change_zabbix_configfile () { # $1 is linke "DBHost",$2 is replace line, $3 is config file uri

    if grep -q "^${1}=" "${3}";then
        sed -i "/^${1}=/c ${2}" "${3}"
    else
        sed -i "/^# ${1}=/c ${2}" "${3}"
    fi
}

set_zabbix_configfile () {
    change_zabbix_configfile "DBName" "DBName=${ZABBIX_DBNAME}" "${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
    change_zabbix_configfile "DBHost" "DBHost=${ZABBIX_DBHOST}" "${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
    change_zabbix_configfile "DBUser" "DBUser=${ZABBIX_DBUSER}" "${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
    change_zabbix_configfile "DBPassword" "DBPassword=${ZABBIX_DBPASSWORD}" "${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
    change_zabbix_configfile "DBPort" "DBPort=${ZABBIX_DBPORT}" "${ZABBIX_INSTALL_PATH}/etc/zabbix_server.conf"
    color "to zabbix_server.conf add database attr." success
}

main () {
    create_account zabbix zabbix
    determine_user
    uncompress_file ${GOLANG_PACK_NAME} ${GO_INSTALL_PATH}
    config_golang_env
    uncompress_zabbix_to_src_path
    complile_zabbix
    create_zabbix_service
    set_zabbix_configfile
}
main